﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Net;
using System.ServiceModel;
using System.Security.Cryptography.X509Certificates;
using System.IdentityModel.Policy;
using System.ServiceModel.Security;
using WCFAuthorization.Server.Security;
using System.Collections.ObjectModel;

namespace WCFAuthorization.Server
{
    [Description("服务器信息")]
    class Server
    {
        public Server()
        {

        }

        int _port = 8866;
        [Category("参数"), DefaultValue(8866), Description("服务端口")]
        public int Port
        {
            get { return _port; }
            set
            {
                if (value <= 0 && value >= 65535)
                    return;
                _port = value;
            }
        }

        string _address = "127.0.0.1";
        [Category("参数"), TypeConverter(typeof(AddressConvert)), Description("绑定地址,须选择公网IP地址")]
        public string Address
        {
            get { return _address; }
            set { _address = value; }
        }

        ServiceHost host = null;

        public bool Start(out string errmsg)
        {
            errmsg = string.Empty;
            try
            {
                Uri uri = new Uri(string.Format("net.tcp://{0}:{1}", _address, _port));

                NetTcpBinding binding = new NetTcpBinding(SecurityMode.Message);
                binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;

                host = new ServiceHost(typeof(WCFAuthorization.Service.Service));
                host.AddServiceEndpoint(typeof(WCFAuthorization.Contract.IContract), binding, uri);

                //必须设置证书才可以使用 UserName模式
                host.Credentials.ServiceCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindByIssuerName, "HandRegisterCretificate");

                //自定义授权管理
                IList<IAuthorizationPolicy> policys = new List<IAuthorizationPolicy>();
                policys.Add(new CustomAuthorizationPolicy());
                host.Authorization.ExternalAuthorizationPolicies = new ReadOnlyCollection<IAuthorizationPolicy>(policys);
                host.Authorization.ServiceAuthorizationManager = new CustomServiceAuthorizationManager();


                //自定义验证
                host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
                host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNameValidator();

                host.Open();
                return true;
            }
            catch (Exception ex)
            {
                errmsg = ex.Message;
            }
            return false;
        }

        public void Stop()
        {
            if (host.State != CommunicationState.Closed)
            {
                try
                {
                    host.Close();
                }
                catch { }
            }
        }
    }

    class AddressConvert : StringConverter
    {
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }

        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            string hostName = Dns.GetHostName();
            IPAddress[] address = Dns.GetHostAddresses(hostName);
            var query = from p in address
                        select p.ToString();
            return new StandardValuesCollection(query.ToList());
        }

        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
        {
            return false;
        }
    }
}
